/*******************************************************************
 * 外语翻译平台(translate) 
 *
 * 成都一亿信息技术公司 版权所有
 * 
 * Copyright (C) 2010 Transer Information Technology Co., Ltd.
 *
 * @Version : 1.0  2010-12-26 下午07:29:59
 *
 * JobQueue.java 
 *
 *******************************************************************/
package com.transer.utils;

import java.util.concurrent.ConcurrentLinkedQueue;

import org.apache.log4j.Logger;

/**
 * class defination are there
 * 
 * @author Mark
 * 
 * @version 1.0 ywengineer@gmail.com
 * 
 */
public final class JobQueue {
	private static final Logger _log = Logger.getLogger(JobQueue.class);
	private ConcurrentLinkedQueue<Runnable> jobs = new ConcurrentLinkedQueue<Runnable>();
	private Thread runner;
	private Runnable currentJob;
	private long lastPeekTime = 0;
	private int timeout = 1000;
	private int lastQueueSize = 0;
	private int queueState = 0;

	public JobQueue() {
	}

	public JobQueue(ConcurrentLinkedQueue<Runnable> jobs) {
		if (jobs == null)
			return;
		this.jobs = jobs;
	}

	public void start() {
		if (runner == null) {
			runner = new Runner();
			runner.setDaemon(true);
			runner.start();
		}
	}

	public Thread getRunner() {
		return runner;
	}

	public ConcurrentLinkedQueue<Runnable> getJobs() {
		return jobs;
	}

	public void peek(long currentTime) {
		if (lastPeekTime == 0) {
			lastPeekTime = currentTime;
			lastQueueSize = jobs.size();
		} else if (currentTime - lastPeekTime >= timeout) {
			if (jobs.size() >= lastQueueSize) {
				queueState++;
			} else {
				queueState = 0;
			}
			lastQueueSize = jobs.size();
			lastPeekTime = currentTime;
		}
	}

	public int getJobCount() {
		return jobs.size();
	}

	public void stop() {
		if (runner != null) {
			runner.interrupt();
			runner = null;
		}

		if (currentJob != null) {
			currentJob = null;
		}
		jobs = null;
	}

	public void addJob(Runnable job) {
		jobs.add(job);
	}

	private Runnable getNextJob() {
		while (jobs.size() <= 0 && runner != null) {
			try {
				Thread.sleep(5);
			} catch (InterruptedException e) {
				e.printStackTrace();
				break;
			}
		}
		if (jobs.size() > 0) {
			Runnable job = jobs.poll();
			return job;
		} else {
			return null;
		}
	}

	public int getTimeout() {
		return timeout;
	}

	public void setTimeout(int timeout) {
		this.timeout = timeout;
	}

	public int getQueueState() {
		return queueState;
	}

	public void setQueueState(int queueState) {
		this.queueState = queueState;
	}

	private class Runner extends Thread {
		public Runner() {
			super("JobQueueRunner Thread");
		}

		public void run() {
			while (runner == this) {
				Runnable job = getNextJob();
				if (job == null) {
					continue;
				}
				if (runner != this) {
					break;
				}
				try {
					currentJob = job;
					job.run();
				} catch (Throwable e) {
					_log.error("JobQueue error", e);
					e.printStackTrace();
				}
			}
			runner = null;
		}
	}
}
